home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume15 / hash8 < prev    next >
Encoding:
Internet Message Format  |  1988-06-05  |  32.6 KB

  1. Subject:  v15i036:  Hash long identifiers into unique short ones
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: desint!geoff (Geoff Kuenning)
  7. Posting-number: Volume 15, Issue 36
  8. Archive-name: hash8
  9.  
  10. [  I haven't used this; documentation is in the README files as use
  11.    is likely to be very system-dependent. --r$  ]
  12.  
  13. This is Arch Robison's "hash8" program, which allows old C compilers
  14. to compile long-identifier programs correctly.  I have added an "lcc"
  15. ("longname-cc") shell script to make this even easier.  Useful with
  16. ispell and nethack.
  17.  
  18.     Geoff Kuenning   geoff@ITcorp.com   {uunet,trwrb}!desint!geoff
  19.  
  20. #! /bin/sh
  21. # This is a shell archive, meaning:
  22. # 1. Remove everything above the #! /bin/sh line.
  23. # 2. Save the resulting text in a file.
  24. # 3. Execute the file with /bin/sh (not csh) to create the files:
  25. #    README
  26. #    README.OLD
  27. #    DOC
  28. #    Makefile
  29. #    hash8.c
  30. #    lcc.sh,v
  31. #    ltest.c
  32. #    ltest2.c
  33. #    ltest3.c
  34. #    ncc
  35. export PATH; PATH=/bin:$PATH
  36. echo shar: extracting "'README'" '(873 characters)'
  37. if test -f 'README'
  38. then
  39.     echo shar: will not over-write existing file "'README'"
  40. else
  41. cat << \SHAR_EOF > 'README'
  42.  
  43.     An Improved Version of Arch Robison's "hash8"
  44.  
  45. Some time ago, Arch Robison kindly provided me with a copy of his
  46. "hash8" program, which gives long-id capabilities to all C compilers.
  47. Briefly, hash8 replaces all long identifiers in a program with a
  48. numerically-based identifier of 6 characters.  Options allow things
  49. like using debuggers with the original long names.
  50.  
  51. I have extended Arch's program with a shell script, "lcc.sh", which
  52. does exactly what "cc" does, but compiles long-name programs.  Unfortunately,
  53. the script is quite system-specific, and I have an odd configuration
  54. (68000 running UniSoft System V.0 with V7 compilers), so you will
  55. almost certainly have to edit it before it is completely compatible
  56. with your own "cc".  Nevertheless, for those with older compilers,
  57. this is a life-saver.
  58.  
  59.     Geoff Kuenning   geoff@ITcorp.com   {uunet,trwrb}!desint!geoff
  60. SHAR_EOF
  61. fi # end of overwriting check
  62. echo shar: extracting "'README.OLD'" '(1303 characters)'
  63. if test -f 'README.OLD'
  64. then
  65.     echo shar: will not over-write existing file "'README.OLD'"
  66. else
  67. cat << \SHAR_EOF > 'README.OLD'
  68. >From uucp Sat Oct 25 02:45 PDT 1986
  69. >From ihnp4!uiucdcs!b.cs.uiuc.edu!robison  Sat Oct 25 02:45:46 1986 remote from trwrb
  70. Received: by ihnp4.ATT.COM id AA14044; 22 Oct 86 15:34:56 CDT (Wed)
  71. Received: from b.cs.uiuc.edu by a.cs.uiuc.edu with SMTP (UIUC-5.44/9.7),
  72.     id AA26838; Wed, 22 Oct 86 11:29:19 CDT
  73. Received: by b.cs.uiuc.edu (UIUC-5.44/9.7),
  74.     id AA04280; Wed, 22 Oct 86 11:25:50 CDT
  75. Date: Wed, 22 Oct 86 11:25:50 CDT
  76. From: trwrb!ihnp4!uiucdcs!b.cs.uiuc.edu!robison (Arch Robison)
  77. Message-Id: <8610221625.AA04280@b.cs.uiuc.edu>
  78. To: desint!geoff
  79. Subject: long-to-short converter
  80.  
  81.  
  82. Here is the long-identifier converter.  The converter has been used
  83. to create a long-identifier lint and with cc.  Please send me any bug
  84. reports or comments on how to improve it.  My version of lint that uses 
  85. it has been running for nearly a year now without problems.  Since lint
  86. is a licensed program, I can't send you a copy, though it shouldn't be 
  87. hard to figure out how to modify it.  (Lint is a shell script.)
  88.  
  89. To use hash8 with debuggers, you will want to modify it to turn off 
  90. stdin/stdout buffering.
  91.  
  92. To compile the program, make a directory and run the shell script below.
  93. Then "make hash8".
  94.  
  95. - Arch D. Robison
  96.   Dept. of Computer Science
  97.   University of Illinois at Urbana-Champaign
  98.  
  99.   robison@uiucdcs
  100.  
  101. SHAR_EOF
  102. fi # end of overwriting check
  103. echo shar: extracting "'DOC'" '(1324 characters)'
  104. if test -f 'DOC'
  105. then
  106.     echo shar: will not over-write existing file "'DOC'"
  107. else
  108. cat << \SHAR_EOF > 'DOC'
  109. Hash8 documentation                Arch D. Robison
  110.                         University of Illinois
  111.                         Urbana Champaign
  112.  
  113.                         robison@uiucdcs
  114.  
  115.             Hash8 
  116.  
  117. There three files (other than DOC) provided:
  118.  
  119.     hash8.c     source code for long identifier converter
  120.     Makefile    example makefile
  121.     ncc        shell script for compiling
  122.  
  123. The hash8 program allows short-identifier C compilers to compile
  124. long-identifier programs.  It is not intened for production use,
  125. but for quickly porting long-identifier programs.
  126.  
  127. See the documentation in hash8.c and the Makefile for how to use it with cc.
  128.  
  129. ----------------------------------------------------------------------
  130.  
  131.             Hash8 with lint
  132.  
  133. I've been able to hack a short identifier lint with "hash8" so it would work
  134. with long identifier programs.  This was an easy modification since lint is
  135. a shell script.  The "hash8 encode" filter was put in between /lib/cpp and 
  136. /usr/lib/lint/lint and all error message written to a temporary file.
  137. Then "hash8 decode" was used to decode the error messages.
  138.  
  139. Note that hash8's can not run in parallel, since the identifier map is read all
  140. at once and written all at once.
  141.  
  142. Thus you can't (regrettably) do: 
  143.  
  144.      hash8 encode TABLE | /lib/cpp | hash8 decode TABLE
  145.  
  146. The above would have to be written:
  147.  
  148.      hash8 encode TABLE >TEMP
  149.      cat TEMP | /lib/cpp | hash8 decode TABLE
  150.  
  151. SHAR_EOF
  152. fi # end of overwriting check
  153. echo shar: extracting "'Makefile'" '(1829 characters)'
  154. if test -f 'Makefile'
  155. then
  156.     echo shar: will not over-write existing file "'Makefile'"
  157. else
  158. cat << \SHAR_EOF > 'Makefile'
  159. # Here is the original makefile for a sample program with long identifiers.
  160. #
  161. #snakeomatic:    main.o move.o screen.o
  162. #        cc main.o move.o screen.o -lm
  163. #
  164. #main.o:    snakeomatic.h main.c
  165. #        cc -c main.c
  166. #
  167. #move.o:        snakeomatic.h move.c
  168. #        cc -c move.c
  169. #
  170. #screen.o:    snakeomatic.h screen.c
  171. #        cc -c screen.c
  172.  
  173. #---------------------------------------------------------------------------
  174. #
  175. # Makefile modified for hash8.  Each source file xxx has been renamed L_xxx.
  176. # The "ncc" shell script filters each L_xxx file with hash8 and puts
  177. # the result in file xxx, which is then compiled.
  178. #
  179. # Also note that any .h file must also be filtered by hash8.
  180. #
  181. # The file TABLE is the identifier mapping table.  You should "make TABLE"
  182. # before your first compilation to initilize the mapping table.
  183. # After that, you should not have to remake the table, even if you
  184. # make corrections in the code.  Hash8 will automatically update
  185. # the table when necessary.
  186. #
  187. SYSTEM = /usr/include/stdio /usr/include/signal.h /usr/include/sgtty.h 
  188.  
  189. snakeomatic:    main.o move.o screen.o
  190.         cc main.o move.o screen.o -lm 2>&1 | hash8 _decode TABLE
  191.  
  192. main.o:        snakeomatic.h L_main.c
  193.         ncc main.c
  194.  
  195. move.o:        snakeomatic.h L_move.c
  196.         ncc move.c
  197.  
  198. screen.o:    snakeomatic.h L_screen.c
  199.         ncc screen.c
  200.  
  201. snakeomatic.h:  L_snakeomatic.h
  202.         cat L_snakeomatic.h | hash8 encode TABLE >snakeomatic.h
  203.  
  204. #
  205. # When the identifier map is first created, all the system #include files
  206. # should be run through hash8.  This usually not necessary, but it
  207. # is possible that your program's identifiers could have a common prefix
  208. # with a system identifier.  By processing the system #include files first,
  209. # we ensure that those identifiers will not be changed.
  210. #
  211. TABLE:        hash8 $(SYSTEM)
  212.         rm -f TABLE
  213.         cat $(SYSTEM) | hash8 encode TABLE >/dev/null
  214.  
  215. hash8:        hash8.c
  216.         cc $(CFLAGS) hash8.c -o hash8
  217. SHAR_EOF
  218. fi # end of overwriting check
  219. echo shar: extracting "'hash8.c'" '(11200 characters)'
  220. if test -f 'hash8.c'
  221. then
  222.     echo shar: will not over-write existing file "'hash8.c'"
  223. else
  224. cat << \SHAR_EOF > 'hash8.c'
  225. /*
  226.  * Date: March 17 1985            Author: Arch D. Robison
  227.  *                        Dept. of Computer Science
  228.  *                        University of Illinois
  229.  *                        Urbana-Champaign
  230.  *
  231.  *                    USENET:    robison@uiucdcs
  232.  *
  233.  * Hash8 copies stdin to stdout, while replacing certain identifiers.
  234.  * lint can be converted to accept long identifiers by hacking in hash8
  235.  * between /lib/cpp and /usr/lib/lint/lint appropriately.
  236.  *
  237.  * There are three ways to call hash8:
  238.  *
  239.  *     hash8 encode table
  240.  *         Map long identifiers and those beginning with Q 
  241.  *       into short identifiers Q%d
  242.  *
  243.  *     hash8 decode table
  244.  *         Map short identifiers Q%d into their long equivalents
  245.  *
  246.  *     hash8 _decode table
  247.  *         Map short identifiers _Q%d into their long equivalents
  248.  *        This is used to decode the linker's error messages
  249.  *
  250.  * The 'table' argument is the file name for the identifier map.
  251.  * The 'encode' calls will either create or expand the table.
  252.  *
  253.  * Typically, the encode option is used to preprocess input to the compiler
  254.  * or lint, and the decode option is used to decode error messages from
  255.  * the compiler.
  256.  *
  257.  * The constant HASHBITS may need to be changed.  It is the base two
  258.  * log of the number of distinct long identifiers which may be found.
  259.  * E.g. the value of 12 allows for 4096 long identifiers.
  260.  *
  261.  * Hash8 has not been thoroughly tested, though it can translate itself
  262.  * correctly.  Note that itself contains all sorts of quotes within quotes.
  263.  */
  264. #include <stdio.h>
  265. #include <ctype.h>
  266.  
  267. /*
  268.  * Reserved is an array of words which we don't want modified, such
  269.  * as the key word "register", or system functions longer than 7 characters.
  270.  * Feel free to add any others, though remember to clear your hash table
  271.  * files after recompiling.
  272.  */
  273. char **Reserved = NULL;
  274. int Res_max = 0;
  275. int Res_count = 0;
  276. char *Def_reserved[] = {
  277.    "continue",
  278.    "register",
  279.    "unsigned"
  280. };
  281.  
  282. extern char *malloc (), *strcpy ();
  283.  
  284. #define SIGCHARS 7        /* significant characters in identifier */
  285. #define HASHBITS 12        /* hash table address size */
  286. #define HASHLIMIT (1<<HASHBITS)
  287. #define HASHMASK (HASHLIMIT-1)
  288. #define PAGESIZE 4096        /* Memory allocation pagesize */ 
  289. #define MAXLINE 1024        /* Maximum length of a source line allowed */
  290.  
  291. #define W_SHORTEN  0        /* Identifier classes */
  292. #define W_NORMAL   1
  293. #define W_RESERVED 2
  294. #define W_Valid(N) ((N) >= 0 && (N) <= 2)
  295.  
  296. /*
  297.  * HashTab
  298.  *
  299.  * The identifier map is a hash table.  The table uses open addressing
  300.  * with linear probing for collision resolution.  Identifiers in the
  301.  * table are mapped into Qxxx, where xxx is the table address in hex.
  302.  *
  303.  * The hash table is effectively declared:
  304.  *
  305.  *      char *HashTab[HASHLIMIT];
  306.  *
  307.  * though the memory allocation is done with malloc.  Each empty hash table
  308.  * item is NULL.  Full entries point to an identifier.  The first byte of
  309.  * the identifier classifies the identifier:
  310.  *
  311.  *      W_NORMAL - don't modify this identifier
  312.  *    W_SHORTEN - shorten this identifier
  313.  *    W_RESERVE - reserved word 
  314.  */
  315. char **HashTab;
  316. int HashSize = 0;    /* Number of elements in hash table             */
  317. int NewTab;          /* Flag which is set to true if hash table is modified */
  318.  
  319. char *StrFree;         /* Pointer to base of free string area                 */
  320. int StrLeft = 0;     /* Number of characters left in free string area       */
  321.  
  322. /*
  323.  * Insert
  324.  * 
  325.  * Insert identifier in hash table
  326.  *
  327.  * In
  328.  *      k = index into hash table
  329.  *      S = identifier
  330.  *    Class = class of identifier (W_NORMAL,W_SHORTEN,W_RESERVED)
  331.  */
  332. void Insert (k,S,Class)
  333.    int k;
  334.    char *S;
  335.    int Class;
  336.    {
  337.       register int L;
  338.  
  339.       NewTab = 1;
  340.       HashSize++;
  341.       if ((StrLeft -= (L=2+strlen (S))) < 0)
  342.          StrFree = malloc (StrLeft=PAGESIZE);
  343.       *(HashTab[k] = StrFree) = Class;
  344.       strcpy (StrFree+1, S);
  345.       StrFree += L;
  346.       StrLeft -= L;
  347.    }               
  348.  
  349. /*
  350.  * LookUp
  351.  *
  352.  * Look up an identifer in the identifier hash table.
  353.  * If not found, then insert it in the table.
  354.  *
  355.  * The hashing uses open addressing with linear probing.
  356.  * The algorithm is a blue-light special, a better hash function
  357.  * (double hashing?) should be used.
  358.  * 
  359.  * In
  360.  *      S = identifier (must be at least seven characters if Duplicate == 0)
  361.  *      Class = identifier class (W_NORMAL,W_SHORTEN,W_RESERVED)
  362.  * Out
  363.  *      result = index into hash table 
  364.  */
  365. int LookUp (S,Class)
  366.    char *S;
  367.    int Class;
  368.    {
  369.       register int k,j;
  370.       register char *T;
  371.  
  372.       if (Class != W_SHORTEN) {
  373.  
  374.          /* Hash first seven characters of identifier */ 
  375.          for (j=0,k=0,T=S; j<SIGCHARS; j++, k+= *T++) k = (k<<1) + k;
  376.  
  377.          /* 7-character search for identifier in table */
  378.          for (j=k; HashTab[j&=HASHMASK] != NULL; j++) 
  379.             if (!strncmp (HashTab[j]+1,S,SIGCHARS)) 
  380.                if (!strcmp (HashTab[j]+1,S)) return j;
  381.            else {
  382.           Class = W_SHORTEN;
  383.           break;
  384.            }
  385.      /* The following test and assignment cause identifiers to be
  386.       * hashed even if they are the first long identifier.  This
  387.       * protects from truncation by the compiler.  Othewise, when
  388.       * you run adb you have to know which long id came first.
  389.       * Geoff Kuenning 11/8/86
  390.       */
  391.          if (Class == W_NORMAL  &&  strlen (S) > SIGCHARS)
  392.         Class = W_SHORTEN;
  393.       }
  394.  
  395.       if (Class == W_SHORTEN) {
  396.      /* 
  397.       * There is another identifier with the same 7-character prefix. 
  398.       * Hash the complete identifier and look it up in the table.
  399.       */
  400.          for (j=k; *T; j+= *T++) j = (j<<1) + j;
  401.  
  402.      /* all characters search for identifier in table */
  403.      for (; HashTab[j&=HASHMASK] != NULL; j++)
  404.            if (!strcmp (HashTab[j]+1,S)) return j;
  405.       }
  406.  
  407.       /* Identifier was not found - insert it in hash table */
  408.       Insert (j,S,Class);
  409.       if (HashSize == HASHLIMIT) 
  410.      fprintf (stderr,"hash8: table overflow\n"), exit (1);
  411.       return j;
  412.    }
  413.  
  414. #define C_CODE 0    /* Defines for translator states */
  415. #define S_QUOTE 1
  416. #define D_QUOTE 2
  417. #define COMMENT 3
  418.  
  419. #define ENCODE 0    /* Mode values for translator */
  420. #define DECODE 1
  421. #define _DECODE 2
  422.  
  423. /*
  424.  * Translate
  425.  *
  426.  * Translate input stream with identifier map.
  427.  *
  428.  * This should have been written with lex.
  429.  */
  430. Translate (Mode) 
  431.    int Mode;
  432.    {
  433.       register char C, *P, *Q;
  434.       char S[MAXLINE];
  435.       int k, state=C_CODE, IsQ;
  436.  
  437.       while (NULL != fgets (S,MAXLINE,stdin)) 
  438.          for (P=S; C= *P; )
  439.         switch (state) {
  440.            case COMMENT:
  441.               putchar (*P++);
  442.                   if (C == '*' && *P == '/') state=C_CODE, putchar (*P++);
  443.           break;
  444.            case S_QUOTE:
  445.            case D_QUOTE:
  446.           putchar (*P++);
  447.           switch (C) {
  448.              case '\'': if (state == S_QUOTE) state = C_CODE; break;
  449.              case '"' : if (state == D_QUOTE) state = C_CODE; break;
  450.              case '\\': putchar (*P++); break;
  451.              default: break; 
  452.           }
  453.               break;
  454.            
  455.                case C_CODE:
  456.           if (isalpha (C) || C=='_') {
  457.                  /* Beginning of identifier */
  458.                        for (Q=P; C= *Q, isalnum(C)||C=='_'; Q++);
  459.                  *Q = '\0';
  460.                     switch (Mode) {
  461.  
  462.             case ENCODE: /* We are encoding C source */
  463.                    IsQ = *P=='Q' && isdigit (P[1]);
  464.                           if (Q-P <= SIGCHARS && !IsQ) 
  465.                              fputs (P,stdout);
  466.                    else {
  467.                   k = LookUp (P,IsQ ? W_SHORTEN : W_NORMAL);
  468.                   if (*HashTab[k] != W_SHORTEN) fputs (P,stdout);
  469.                       else printf ("Q%d",k);
  470.                    }
  471.                break;
  472.  
  473.             case _DECODE: /* We are decoding linker messages */
  474.                    if (*P != '_') {
  475.                   fputs (P,stdout);
  476.                   break;
  477.                }
  478.                putchar (*P++);
  479.                /* continue on down to case DECODE */
  480.  
  481.             case DECODE: /* We are decoding error message */
  482.                           if (*P=='Q' && isdigit (P[1])) { 
  483.                   k=atoi(P+1);
  484.                   if (!(k &~HASHMASK) && HashTab[k]!=NULL) 
  485.                  P = HashTab[k] + 1;
  486.                }
  487.                    fputs (P,stdout);
  488.                break;
  489.              }
  490.                     *(P=Q) = C;
  491.                  } else if (isdigit (C)) {
  492.                  /* Skip number to avoid changing long numbers */
  493.                  while (isalnum(*P)) putchar (*P++);
  494.               } else {
  495.              putchar (*P++);
  496.              switch (C) {
  497.                 default: break;
  498.             case '\'': state = S_QUOTE; break;
  499.                         case '"' : state = D_QUOTE; break;
  500.                         case '/' : if (*P != '*') continue;
  501.                        state=COMMENT;
  502.                 case '\\': putchar (*P++); break;
  503.              }
  504.               }
  505.            }
  506.    }
  507.  
  508. /*
  509.  * ReadTab
  510.  *
  511.  * Read the hash table.
  512.  *
  513.  * In
  514.  *      Name = name of hash table file
  515.  */
  516. ReadTab (Name)
  517.    char *Name;
  518.    {
  519.       FILE *Table;
  520.       char S[MAXLINE];
  521.       int k,L,Class;
  522.  
  523.       /* First record all words we don't want mangled in hash table */      
  524.       for (k = 0;  k < sizeof (Def_reserved) / sizeof (char *);  k++)
  525.          LookUp (Def_reserved[k], W_RESERVED);
  526.       for (k = 0;  k < Res_count;  k++) 
  527.          LookUp (Reserved[k],W_RESERVED);
  528.  
  529.       if (NULL == (Table = fopen (Name,"r"))) return;
  530.       while (EOF != (L = fscanf (Table,"%d %d %s",&k,&Class,S))) 
  531.      if (L != 3 || k &~HASHMASK || !W_Valid (Class))
  532.         fprintf (stderr,"hash8 table error\n"),
  533.         exit (1);
  534.          else Insert (k,S,Class);
  535.       fclose (Table); 
  536.       NewTab = 0;
  537.    }
  538.  
  539. /*
  540.  * WriteTab
  541.  *
  542.  * Write out the hash table
  543.  *
  544.  * In
  545.  *      Name = name of hash table file
  546.  */
  547. WriteTab (Name)
  548.    char *Name; 
  549.    { 
  550.       FILE *Table;
  551.       int i;
  552.  
  553.       if (NULL == (Table = fopen (Name,"w"))) 
  554.      fprintf (stderr,"hash8: can't open hash table file '%s'\n",Name),
  555.      exit (1);
  556.       for (i=0; i<HASHLIMIT; i++)
  557.          if (HashTab[i] != NULL && *HashTab[i] != W_RESERVED) 
  558.             fprintf (Table,"%d    %d    %s\n",i,*HashTab[i],HashTab[i]+1);
  559.       fclose (Table); 
  560.    }
  561.  
  562. main (argc,argv)
  563.    int argc; char *argv[];
  564.    {
  565.       register char **h;
  566.       int Mode;
  567.  
  568.       /*
  569.        * Set up the reserved-word list.
  570.        */
  571.       while (argc > 3  &&  argv[1][0] == '-'  &&  argv[1][1] == 'r') {
  572.      argv[1] += 2;
  573.      if (argv[1][0] == '\0') {
  574.         argc--;
  575.         argv++;
  576.      }
  577.      if (Res_count == Res_max) {
  578.         Res_max += 5;
  579.         if (Reserved == NULL)
  580.            Reserved = (char **) malloc (5 * sizeof (char *));
  581.         else
  582.            Reserved = (char **)
  583.             realloc ((char *) Reserved, Res_max * sizeof (char *));
  584.      }
  585.      Reserved[Res_count] = argv[1];
  586.      Res_count++;
  587.      argc--;
  588.      argv++;
  589.       }
  590.       if (argc != 3) {
  591.          fprintf (stderr,
  592.            "usage: hash8 [-r reserved] ... (encode|[_]decode) table\n");
  593.          exit (1);
  594.       }
  595.  
  596.       /*
  597.        * If either stdin or stdout is a tty, set both unbuffered, for use
  598.        * in pipes.
  599.        * Geoff Kuenning, 11/8/86
  600.        */
  601.       if (isatty (fileno (stdin))  ||  isatty (fileno (stdout))) {
  602.      setbuf (stdin, NULL);
  603.      setbuf (stdout, NULL);
  604.       }
  605.       HashTab = (char **) malloc ((sizeof (char*)) * (HASHLIMIT));
  606.       for (h = HashTab+HASHLIMIT; --h > HashTab; ) *h = NULL;
  607.      
  608.       ReadTab(argv[2]); 
  609.       
  610.       if (!strcmp (argv[1],"encode")) Mode = ENCODE;
  611.       else if (!strcmp (argv[1],"decode")) Mode = DECODE; 
  612.       else if (!strcmp (argv[1],"_decode")) Mode = _DECODE; 
  613.       else
  614.          fprintf (stderr,"hash8: second arg must be 'encode' or 'decode'\n"),
  615.      exit (1);
  616.  
  617.       Translate (Mode);
  618.       if (NewTab) WriteTab(argv[2]);
  619.    }
  620.  
  621. SHAR_EOF
  622. fi # end of overwriting check
  623. echo shar: extracting "'lcc.sh,v'" '(11956 characters)'
  624. if test -f 'lcc.sh,v'
  625. then
  626.     echo shar: will not over-write existing file "'lcc.sh,v'"
  627. else
  628. cat << \SHAR_EOF > 'lcc.sh,v'
  629. head     1.5;
  630. access   ;
  631. symbols  ;
  632. locks    ; strict;
  633. comment  @# @;
  634.  
  635.  
  636. 1.5
  637. date     87.03.06.20.34.29;  author geoff;  state Exp;
  638. branches ;
  639. next     1.4;
  640.  
  641. 1.4
  642. date     87.02.28.00.56.50;  author geoff;  state Exp;
  643. branches ;
  644. next     1.3;
  645.  
  646. 1.3
  647. date     86.11.08.23.07.56;  author geoff;  state Exp;
  648. branches ;
  649. next     1.2;
  650.  
  651. 1.2
  652. date     86.11.08.22.15.24;  author geoff;  state Exp;
  653. branches ;
  654. next     1.1;
  655.  
  656. 1.1
  657. date     86.11.08.21.58.14;  author geoff;  state Exp;
  658. branches ;
  659. next     ;
  660.  
  661.  
  662. desc
  663. @Shell script to compile long-name C programs.
  664. @
  665.  
  666.  
  667. 1.5
  668. log
  669. @Make -p work correctly
  670. @
  671. text
  672. @: Use bin/sh
  673. #
  674. # $Header: lcc.sh,v 1.4 87/02/28 00:56:50 geoff Exp $
  675. #
  676. # $Log:    lcc.sh,v $
  677. # Revision 1.4  87/02/28  00:56:50  geoff
  678. # Major changes to handle things much better by running each compiler
  679. # pass separately.  Also add the -R switch, and support for -D and
  680. # library files.
  681. # Revision 1.3  86/11/08  23:07:56  geoff
  682. # Add error processing, not quite like cc's
  683. # Revision 1.2  86/11/08  22:15:24  geoff
  684. # Remove -HP, minor cleanup of output.  Working, except ignores errors
  685. # Revision 1.1  86/11/08  21:58:14  geoff
  686. # Works only if -HP specified
  687. #
  688. #    Replacement for the 'cc' command, with support for long
  689. #    identifiers.
  690. #
  691. #    Usage:
  692. #
  693. #    lcc [options] files
  694. #
  695. #    As with 'cc', the files mentioned can be .c, .s, or .o files.
  696. #
  697. #    All 'cc' options are support (or should be -- report bugs!).
  698. #
  699. #    There are some extra options.  All begin with H:
  700. #
  701. #    -HD    Don't preserve the encode/decode table.  (Normally, it is
  702. #        left in xxxx.t, where xxxx is the first file name encountered,
  703. #        or the -o file name if -o is specified.)
  704. #    -HA name The encode/decode table is put in <name>.  If it exists,
  705. #        the program will append to it.
  706. #    -HL    Only the C compiler itself is deficient;  the assembler
  707. #        and linker can handle long names.  Use this facility to
  708. #        generate long-name object files.  This is incompatible
  709. #        with -P and -S, but conflict is not checked.
  710. #    -R name    Add <name> to the reserved-word list.  Useful for
  711. #        library routines that have long names.
  712. #
  713. #    Options supported:
  714. #
  715. #    -I<dir>    Set include path for cpp
  716. #    -S    Generate .s files
  717. #    -c    Generate .o files;  don't load
  718. #    -n    Generate shared text (ld)
  719. #    -p    Generate profiled output
  720. #    -f*    Passed on to cc
  721. #
  722. TDIR=${TMPDIR:-/tmp}        # Where to put temp files
  723. TFILE=lcc$$            # Base name for encoded source files
  724. TMP=$TDIR/$TFILE        # Base name of cc's encoded input files
  725. TABLE=${TFILE}t            # Where the decode file goes
  726. c1sw=                # Switches for compiler pass 1
  727. ccsw=                # Switches for cc
  728. ldsw=                # Switches for ld
  729. suffix=o            # Suffix of output "object" files:  o, s, or i
  730. forceobj=-c            # How to force "objects":  -c, -P, or -S
  731. load=yes            # Yes to invoke loader
  732. numsrcfiles=            # If this is exactly one x, we kill objects
  733. ofiles=                # Files to be linked
  734. optimize=no            # -O switch specified
  735. optsw=                # Switches for optimizer
  736. preprocess=            # Preprocess option:  null, -P, or -E
  737. reserved=            # Reserved-word list
  738. rmfiles=            # List of object files to remove (only one)
  739. verbose=            # Verbose option:  -v or null
  740. killtable=no            # Yes if $TABLE is to be deleted
  741. tablename=            # Name of the output table
  742. madetable=no            # Yes if we added to the table
  743. dumbcc=no            # Yes if only cc is dumb about long names
  744.  
  745. if [ -x /lib/c ]
  746. then
  747.     COMPILER=/lib/c
  748. elif [ -x /usr/lib/c ]
  749. then
  750.     COMPILER=/usr/lib/c
  751. else
  752.     COMPILER=c
  753. fi
  754. if [ -x /lib/c2 ]
  755. then
  756.     OPTIMIZER=/lib/c2
  757. elif [ -x /usr/lib/c2 ]
  758. then
  759.     OPTIMIZER=/usr/lib/c2
  760. else
  761.     OPTIMIZER=c2
  762. fi
  763. trap '/bin/rm -f ${TFILE}.? ${TMP}* $TABLE; exit 1' 1 2 15
  764. # 7 is SIGEMT, a fairly obscure one
  765. failure=no
  766. trap "failure=yes" 7
  767. while [ $# -gt 0 ]
  768. do
  769.     case "$1" in
  770.     -HD)
  771.         TABLE=${TMP}t    # Put output table in $TMPDIR
  772.         killtable=yes
  773.         ;;
  774.     -HA)
  775.         tablename=$2
  776.         TABLE=$2
  777.         shift
  778.         ;;
  779.     -HL)
  780.         dumbcc=yes
  781.         ;;
  782.     -R)
  783.         reserved="$reserved -r $2"
  784.         shift
  785.         ;;
  786.     -n)
  787.         ldsw="$ldsw $1"
  788.         ;;
  789.     -v)
  790.         verbose=-v
  791.         ;;
  792.     -p)
  793.         ldsw="$ldsw $1"
  794.         c1sw="$c1sw -Xp"
  795.         ;;
  796.     -f*)
  797.         ldsw="$ldsw $1"
  798.         c1sw="$c1sw $1"
  799.         ;;
  800.     -o)
  801.         ldsw="$ldsw $1 $2"
  802.         tablename=$2.t
  803.         shift
  804.         ;;
  805.     -R)
  806.         ldsw="$ldsw $1 $2"
  807.         shift
  808.         ;;
  809.     -E|-P)
  810.         preprocess=$1
  811.         forceobj=$1
  812.         suffix=i
  813.         load=no
  814.         ;;
  815.     -O*)
  816.         optimize=yes
  817.         optsw=`echo $1 | tr -d O`
  818.         if [ "X$optsw" = "X-" ]
  819.         then
  820.         optsw=
  821.         fi
  822.         ;;
  823.     -C|-D*|-U*|-I*)
  824.         ccsw="$ccsw $1"
  825.         ;;
  826.     -S)
  827.         forceobj=-S
  828.         suffix=s
  829.         load=no
  830.         numsrcfiles=xx
  831.         ;;
  832.     -c)
  833.         load=no
  834.         numsrcfiles=xx
  835.         ;;
  836.     -l*)
  837.         ofiles="$ofiles $1"
  838.         ;;
  839.     *.o)
  840.         numsrcfiles=xx
  841.         ofiles="$ofiles $1"
  842.         if [ "$tablename" = "" ]
  843.         then
  844.         tablename=`basename $1 .o`.t
  845.         fi
  846.         ;;
  847.     *.s)
  848.         if  [ "$dumbcc" = "yes" -a "X$preprocess" = "X" ]
  849.         then
  850.         if cc $ccsw $verbose $forceobj $1
  851.         then
  852.             :
  853.         else
  854.             failure=yes
  855.             break
  856.         fi
  857.         elif [ "$suffix" != "s" -a "X$preprocess" = "X" ]
  858.         then
  859.         hash8 $reserved encode $TABLE < $1 > ${TMP}.s
  860.         madetable=yes
  861.         (cc $ccsw $forceobj $verbose ${TMP}.s 2> ${TMP}.e \
  862.             ||  kill -7 $$) \
  863.           | sed "s;${TMP}.s;$1;" | hash8 decode $TABLE
  864.         sed "s;${TMP}.s;$1;" ${TMP}.e | hash8 decode $TABLE 1>&2
  865.         if [ "$failure" = "yes" ]
  866.         then
  867.             break
  868.         fi
  869.         obj=`basename "$1" '.s'`.$suffix
  870.         ofiles="$ofiles $obj"
  871.         rmfiles="$rmfiles $obj"
  872.         mv ${TFILE}.$suffix $obj
  873.         numsrcfiles="x$numsrcfiles"
  874.         fi
  875.         if [ "$tablename" = "" ]
  876.         then
  877.         tablename=`basename $1 .s`.t
  878.         fi
  879.         ;;
  880.     *.c)
  881.         obj=`basename "$1" '.c'`.$suffix
  882.         ppfile=${TMP}.i
  883.         if [ "X$verbose" = "X-v" ]
  884.         then
  885.         echo "${1}:"
  886.         echo "  Preprocessing" 1>&2
  887.         fi
  888.         if [ "X$preprocess" = "X-E" ]
  889.         then
  890.         if cc $ccsw $preprocess $1
  891.         then
  892.             :
  893.         else
  894.             failure=yes
  895.         fi
  896.         elif [ "X$preprocess" = "X-P" ]
  897.         then
  898.         ppfile=$obj
  899.         fi
  900.         if cc $ccsw -E $1 > $ppfile
  901.         then
  902.         :
  903.         else
  904.         failure=yes
  905.         /bin/rm -f $ppfile
  906.         break
  907.         fi
  908.         if [ "X$preprocess" = "X-P" ]
  909.         then
  910.         break
  911.         fi
  912.         hash8 $reserved encode $TABLE < $ppfile > ${TMP}.c
  913.         madetable=yes
  914.         /bin/rm -f $ppfile
  915.         if [ "$optimize" = yes ]
  916.         then
  917.         unoptfile=${TMP}.s1
  918.         else
  919.         unoptfile=${TMP}.s
  920.         fi
  921.         if [ "X$verbose" = "X-v" ]
  922.         then
  923.         echo "  Compiling" 1>&2
  924.         fi
  925.         if $COMPILER $c1sw < ${TMP}.c > $unoptfile 2> ${TMP}.e
  926.         then
  927.         /bin/rm -f ${TMP}.c
  928.         else
  929.         hash8 decode $TABLE < ${TMP}.e 1>&2
  930.         /bin/rm $unoptfile ${TMP}.c ${TMP}.e
  931.         failure=yes
  932.         break
  933.         fi
  934.         if [ $optimize = yes ]
  935.         then
  936.         if [ "X$verbose" = "X-v" ]
  937.         then
  938.             echo "  Optimizing" 1>&2
  939.         fi
  940.         if $OPTIMIZER $optsw < $unoptfile > ${TMP}.s 2> ${TMP}.e
  941.         then
  942.             /bin/rm -f $unoptfile
  943.             unoptfile=${TMP}.s
  944.         else
  945.             hash8 decode $TABLE < ${TMP}.e 1>&2
  946.             /bin/rm -f $unoptfile ${TMP}.s ${TMP}.e
  947.             failure=yes
  948.             break
  949.         fi
  950.         fi
  951.         case "X$forceobj" in
  952.         X-S)
  953.             hash8 _decode $TABLE < $unoptfile > $obj
  954.             /bin/rm -f $unoptfile
  955.             ;;
  956.         *)
  957.             if [ "X$verbose" = "X-v" ]
  958.             then
  959.             echo "  Assembling" 1>&2
  960.             fi
  961.             if [ "$dumbcc" = "yes" ]
  962.             then
  963.             mv $unoptfile ${TMP}.s1
  964.             hash8 _decode $TABLE < ${TMP}.s1 > ${TMP}.s
  965.             /bin/rm -f ${TMP}.s1
  966.             if as -o $obj ${TMP}.s
  967.             then
  968.                 :
  969.             else
  970.                 /bin/rm -f ${TMP}.s $obj
  971.                 failure=yes
  972.                 break
  973.             fi
  974.             else
  975.             if as -o $obj $unoptfile 2> ${TMP}.e
  976.             then
  977.                 /bin/rm -f $unoptfile ${TMP}.e
  978.             else
  979.                 hash8 _decode $TABLE < ${TMP}.e 1>&2
  980.                 /bin/rm -f $unoptfile ${TMP}.e $obj
  981.                 failure=yes
  982.                 break
  983.             fi
  984.             fi
  985.             ofiles="$ofiles $obj"
  986.             rmfiles="$rmfiles $obj"
  987.             ;;
  988.         esac
  989.         numsrcfiles="x$numsrcfiles"
  990.         if [ "$tablename" = "" ]
  991.         then
  992.         tablename=`basename $1 .c`.t
  993.         fi
  994.         ;;
  995.     *)
  996.         echo "lcc:  unrecognized argument $1, passing to cc and ld" 1>&2
  997.         echo "type 'cat $0' to learn usage"
  998.         ccsw="$ccsw $1"
  999.         ldsw="$ldsw $1"
  1000.         ;;
  1001.     esac
  1002.     shift
  1003. done
  1004. if [ "$load" = yes -a "$failure" = "no" ]
  1005. then
  1006.     if [ "X$verbose" = "X-v" ]
  1007.     then
  1008.     echo "  Loading" 1>&2
  1009.     fi
  1010.     (cc $ldsw $ofiles 2> ${TMP}.e  ||  kill -7 $$) \
  1011.       | if [ "$madetable" = yes ]
  1012.         then
  1013.         hash8 _decode $TABLE
  1014.         hash8 _decode $TABLE < ${TMP}.e 1>&2
  1015.     elif [ -r "$tablename" ]
  1016.     then
  1017.         hash8 _decode $tablename
  1018.         hash8 _decode $tablename < ${TMP}.e 1>&2
  1019.     else
  1020.         cat
  1021.         cat ${TMP}.e 1>&2
  1022.     fi
  1023.     if [ "$numsrcfiles" = x ]
  1024.     then
  1025.     /bin/rm -f $rmfiles
  1026.     fi
  1027. fi
  1028. /bin/rm -f ${TFILE}.? ${TMP}*
  1029. if [ "$killtable" = "yes" -o "$tablename" = "" ]
  1030. then
  1031.     /bin/rm -f $TABLE
  1032. elif [ "$madetable" = yes -a "$TABLE" != "$tablename" ]
  1033. then
  1034.     mv $TABLE $tablename
  1035. fi
  1036. if [ "$failure" = "yes" ]
  1037. then
  1038.     exit 1
  1039. else
  1040.     exit 0
  1041. fi
  1042. @
  1043.  
  1044.  
  1045. 1.4
  1046. log
  1047. @Major changes to handle things much better by running each compiler
  1048. pass separately.  Also add the -R switch, and support for -D and
  1049. library files.
  1050. @
  1051. text
  1052. @d3 1
  1053. a3 1
  1054. # $Header: lcc.sh,v 1.3 86/11/08 23:07:56 geoff Exp $
  1055. d6 5
  1056. d59 1
  1057. d127 1
  1058. a127 1
  1059.         ccsw="$ccsw $1"
  1060. d129 4
  1061. d156 1
  1062. a156 1
  1063.     -f*|-C|-D*|-U*|-I*)
  1064. d258 1
  1065. a258 1
  1066.         if $COMPILER < ${TMP}.c > $unoptfile 2> ${TMP}.e
  1067. @
  1068.  
  1069.  
  1070. 1.3
  1071. log
  1072. @Add error processing, not quite like cc's
  1073. @
  1074. text
  1075. @d3 1
  1076. a3 1
  1077. # $Header: lcc.sh,v 1.2 86/11/08 22:15:24 geoff Exp $
  1078. d6 3
  1079. d37 3
  1080. a39 1
  1081. #        with -P and -S, but conflict is not cheked.
  1082. d61 2
  1083. d64 2
  1084. d72 19
  1085. a90 1
  1086. trap "/bin/rm -f ${TFILE}.? ${TMP}* $TABLE; exit 1" 1 2 15
  1087. a106 2
  1088.         forceobj=-S
  1089.         suffix=s
  1090. d109 4
  1091. d138 9
  1092. a146 1
  1093.     -f*|-O*|-C|-D*|-U*|-I*)
  1094. d159 3
  1095. d182 1
  1096. a182 1
  1097.         hash8 encode $TABLE < $1 > ${TMP}.s
  1098. d194 1
  1099. d204 32
  1100. a235 1
  1101.         hash8 encode $TABLE < $1 > ${TMP}.c
  1102. d237 2
  1103. a238 4
  1104.         (cc $verbose $ccsw $forceobj ${TMP}.c 2> ${TMP}.e  ||  kill -7 $$) \
  1105.           | sed "s;${TMP}.c;$1;" | hash8 decode $TABLE
  1106.         sed "s;${TMP}.c;$1;" ${TMP}.e | hash8 decode $TABLE 1>&2
  1107.         if [ "$failure" = "yes" ]
  1108. d240 15
  1109. d257 27
  1110. a283 5
  1111.         case "X${preprocess}Y$forceobj" in
  1112.         X-P*|*Y-S)
  1113.             obj=`basename "$1" '.c'`.$suffix
  1114.             hash8 _decode $TABLE < ${TFILE}.$suffix > $obj
  1115.             /bin/rm -f ${TFILE}.$suffix
  1116. d286 4
  1117. a289 1
  1118.             if [ "X$verbose" = "X-v" ]
  1119. d291 5
  1120. a295 1
  1121.                 echo "  Assembling" 1>&2
  1122. d297 2
  1123. a298 1
  1124.             if cc $ccsw -c $obj
  1125. d300 1
  1126. a300 1
  1127.                 :
  1128. d302 2
  1129. a306 2
  1130.             /bin/rm -f $obj
  1131.             obj=`basename "$1" '.c'`.o
  1132. d309 1
  1133. a310 7
  1134.         X-E*)
  1135.             ;;
  1136.         *)
  1137.             obj=`basename "$1" '.c'`.$suffix
  1138.             ofiles="$ofiles $obj"
  1139.             mv ${TFILE}.$suffix $obj
  1140.             ;;
  1141. d329 5
  1142. a333 1
  1143.     (cc $verbose $ldsw $ofiles 2> ${TMP}.e  ||  kill -7 $$) \
  1144. d337 1
  1145. d341 1
  1146. d344 2
  1147. a345 1
  1148.     fi 1>&2
  1149. d348 1
  1150. a348 1
  1151.     /bin/rm -f $ofiles
  1152. @
  1153.  
  1154.  
  1155. 1.2
  1156. log
  1157. @Remove -HP, minor cleanup of output.  Working, except ignores errors
  1158. @
  1159. text
  1160. @d3 1
  1161. a3 1
  1162. # $Header: lcc.sh,v 1.1 86/11/08 21:58:14 geoff Exp $
  1163. d6 3
  1164. d64 3
  1165. d133 7
  1166. a139 1
  1167.         cc $ccsw $verbose $forceobj $1
  1168. d144 8
  1169. a151 3
  1170.         (cc $ccsw $forceobj $verbose ${TMP}.s 2>&1 ) \
  1171.           | sed "s;${TMP}.s;$1;" \
  1172.           | hash8 decode $TABLE 1>&2
  1173. d165 1
  1174. a165 1
  1175.         (cc $verbose $ccsw $forceobj ${TMP}.c 2> ${TMP}.e ) \
  1176. d168 4
  1177. d183 7
  1178. a189 1
  1179.             cc $ccsw -c $obj
  1180. d218 1
  1181. a218 1
  1182. if [ "$load" = yes ]
  1183. d220 1
  1184. a220 1
  1185.     (cc $verbose $ldsw $ofiles 2>&1) \
  1186. d243 6
  1187. a248 1
  1188. exit
  1189. @
  1190.  
  1191.  
  1192. 1.1
  1193. log
  1194. @Works only if -HP specified
  1195. @
  1196. text
  1197. @d3 1
  1198. a3 1
  1199. # $Header$
  1200. d5 4
  1201. a8 1
  1202. # $Log$
  1203. a31 3
  1204. #    -HP    Hash before passing information to the preprocessor, rather
  1205. #        than after.  Useful if your preprocessor is dumb.  Conflicts
  1206. #        with -E and -P.
  1207. d53 1
  1208. a53 1
  1209. preprocess=            # Preprocess option:  null, -P, -E, or dumbpp
  1210. a77 4
  1211.     -HP)
  1212.         preprocess=dumbpp
  1213.         load=no
  1214.         ;;
  1215. d146 1
  1216. a146 13
  1217.         if [ "X$preprocess" = "X" ]
  1218.         then
  1219.         #
  1220.         # We preprocess before hashing so that symbols in include
  1221.         # files are picked up.  The disadvantage of this is that
  1222.         # preprocessor names are not shortened, which gives trouble
  1223.         # if your preprocessor is also dumb.  In this case,
  1224.         # specify the -HP switch.
  1225.         #
  1226.         cc $ccsw -E $1 | hash8 encode $TABLE > ${TMP}.c
  1227.         else
  1228.         hash8 encode $TABLE < $1 > ${TMP}.c
  1229.         fi
  1230. d149 1
  1231. a149 1
  1232.           | hash8 decode $TABLE
  1233. d193 1
  1234. a193 1
  1235.     (cc $ldsw $ofiles 2>&1) \
  1236. @
  1237. SHAR_EOF
  1238. chmod +x 'lcc.sh,v'
  1239. fi # end of overwriting check
  1240. echo shar: extracting "'ltest.c'" '(1175 characters)'
  1241. if test -f 'ltest.c'
  1242. then
  1243.     echo shar: will not over-write existing file "'ltest.c'"
  1244. else
  1245. cat << \SHAR_EOF > 'ltest.c'
  1246. #include <stdio.h>
  1247.  
  1248. /*
  1249.  * Test the lcc script
  1250.  */
  1251.  
  1252. int VeryLongIdentifierNumber1 = 1;
  1253. int VeryLongIdentifierNumber2 = 2;
  1254.  
  1255. void VeryLongIdentifierNumber3 ();
  1256. /*
  1257.  * The following should generate a lint complaint, because it actually
  1258.  * returns an int.
  1259.  */
  1260. extern void VeryLongIdentifierNumber4 ();
  1261.  
  1262. /*
  1263.  * The following will generate a loader error.  On some loaders, this is
  1264.  * ok;  on others it will keep you from getting an output file.  If so,
  1265.  * you will need to remove the reference below.
  1266.  */
  1267. extern int VeryLongIdentifierNumber5 ();
  1268.  
  1269. int main (argc, argv)
  1270.     register int        argc;        /* Argument count */
  1271.     register char *        argv[];        /* Argument vector */
  1272.     {
  1273.  
  1274.     /*
  1275.      * Generate a C compiler warning message.  Argv is char **, not char *.
  1276.      */
  1277.     argv = (char *) argc;
  1278.     VeryLongIdentifierNumber3 ();
  1279.     /*
  1280.      * The following is in a second file
  1281.      */
  1282.     VeryLongIdentifierNumber4 ();
  1283.     return 0;
  1284.     }
  1285.  
  1286. void VeryLongIdentifierNumber3 ()
  1287.     {
  1288.     int i = 0;
  1289.  
  1290.     printf ("should print 1 2:  %d %d\n", VeryLongIdentifierNumber1,
  1291.       VeryLongIdentifierNumber2);
  1292.     if (i)                /* Never executed - undefined ref */
  1293.     VeryLongIdentifierNumber5 ();
  1294.     }
  1295. SHAR_EOF
  1296. fi # end of overwriting check
  1297. echo shar: extracting "'ltest2.c'" '(115 characters)'
  1298. if test -f 'ltest2.c'
  1299. then
  1300.     echo shar: will not over-write existing file "'ltest2.c'"
  1301. else
  1302. cat << \SHAR_EOF > 'ltest2.c'
  1303. int VeryLongIdentifierNumber4 ()
  1304.     {
  1305.     printf ("VeryLongIdentifierNumber4 VerylongIdentifierNumber5\n");
  1306.     }
  1307. SHAR_EOF
  1308. fi # end of overwriting check
  1309. echo shar: extracting "'ltest3.c'" '(116 characters)'
  1310. if test -f 'ltest3.c'
  1311. then
  1312.     echo shar: will not over-write existing file "'ltest3.c'"
  1313. else
  1314. cat << \SHAR_EOF > 'ltest3.c'
  1315. int VeryLongIdentifierNumber4 ();
  1316.     {
  1317.     printf ("VeryLongIdentifierNumber4 VerylongIdentifierNumber5\n");
  1318.     }
  1319. SHAR_EOF
  1320. fi # end of overwriting check
  1321. echo shar: extracting "'ncc'" '(314 characters)'
  1322. if test -f 'ncc'
  1323. then
  1324.     echo shar: will not over-write existing file "'ncc'"
  1325. else
  1326. cat << \SHAR_EOF > 'ncc'
  1327.  
  1328. # Shell script for compiling long-identifier programs.
  1329. # (Must be executed by "sh", not "csh".)
  1330. #
  1331. # The long-identifier source should be named L_xxx.
  1332. # The script is then invoked with "ncc xxx"
  1333. #
  1334. cat L_$1 | hash8 encode TABLE >$1    # Convert long identifiers
  1335. cc -c $1 2>&1 | hash8 decode TABLE    # Compile short form
  1336. SHAR_EOF
  1337. fi # end of overwriting check
  1338. #    End of shell archive
  1339. exit 0
  1340.  
  1341.